]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
switcherPopup: Add support for modifier-less keybinding navigation
authorRui Matos <tiagomatos@gmail.com>
Thu, 8 Jun 2017 12:20:56 +0000 (14:20 +0200)
committerRui Matos <tiagomatos@gmail.com>
Tue, 22 Aug 2017 08:50:56 +0000 (10:50 +0200)
This drops the requirement that SwitcherPopups need a modifier based
keybinding to work.

The existing behavior for modifier based keybindings is kept but if
the popup is triggered from a no modifiers keybinding, instead of
finishing when the modifier is released, we use a timer that
automatically finishes the popup. The timer is reset on every key
release to allow navigation to happen.

https://bugzilla.gnome.org/show_bug.cgi?id=783550

js/ui/switcherPopup.js

index d4da7b6b14a25f139d4fd77690a939058bb9f658..0e1f710df72145f555228c95b00338fae9a5856e 100644 (file)
@@ -19,6 +19,7 @@ var POPUP_SCROLL_TIME = 0.10; // seconds
 var POPUP_FADE_OUT_TIME = 0.1; // seconds
 
 var DISABLE_HOVER_TIMEOUT = 500; // milliseconds
+var NO_MODS_TIMEOUT = 1500; // milliseconds
 
 function mod(a, b) {
     return (a + b) % b;
@@ -61,6 +62,7 @@ var SwitcherPopup = new Lang.Class({
 
         this._motionTimeoutId = 0;
         this._initialDelayTimeoutId = 0;
+        this._noModsTimeoutId = 0;
 
         // Initially disable hover so we ignore the enter-event if
         // the switcher appears underneath the current pointer location
@@ -145,10 +147,14 @@ var SwitcherPopup = new Lang.Class({
         // https://bugzilla.gnome.org/show_bug.cgi?id=596695 for
         // details.) So we check now. (Have to do this after updating
         // selection.)
-        let [x, y, mods] = global.get_pointer();
-        if (!(mods & this._modifierMask)) {
-            this._finish(global.get_current_time());
-            return false;
+        if (this._modifierMask) {
+            let [x, y, mods] = global.get_pointer();
+            if (!(mods & this._modifierMask)) {
+                this._finish(global.get_current_time());
+                return false;
+            }
+        } else {
+            this._resetNoModsTimeout();
         }
 
         // We delay showing the popup so that fast Alt+Tab users aren't
@@ -192,11 +198,15 @@ var SwitcherPopup = new Lang.Class({
     },
 
     _keyReleaseEvent: function(actor, event) {
-        let [x, y, mods] = global.get_pointer();
-        let state = mods & this._modifierMask;
-
-        if (state == 0)
-            this._finish(event.get_time());
+        if (this._modifierMask) {
+            let [x, y, mods] = global.get_pointer();
+            let state = mods & this._modifierMask;
+
+            if (state == 0)
+                this._finish(event.get_time());
+        } else {
+            this._resetNoModsTimeout();
+        }
 
         return Clutter.EVENT_STOP;
     },
@@ -253,6 +263,18 @@ var SwitcherPopup = new Lang.Class({
         return GLib.SOURCE_REMOVE;
     },
 
+    _resetNoModsTimeout: function() {
+        if (this._noModsTimeoutId != 0)
+            Mainloop.source_remove(this._noModsTimeoutId);
+
+        this._noModsTimeoutId = Mainloop.timeout_add(NO_MODS_TIMEOUT,
+                                                     Lang.bind(this, function () {
+                                                         this._finish(global.get_current_time());
+                                                         this._noModsTimeoutId = 0;
+                                                         return GLib.SOURCE_REMOVE;
+                                                     }));
+    },
+
     _popModal: function() {
         if (this._haveModal) {
             Main.popModal(this.actor);
@@ -287,6 +309,8 @@ var SwitcherPopup = new Lang.Class({
             Mainloop.source_remove(this._motionTimeoutId);
         if (this._initialDelayTimeoutId != 0)
             Mainloop.source_remove(this._initialDelayTimeoutId);
+        if (this._noModsTimeoutId != 0)
+            Mainloop.source_remove(this._noModsTimeoutId);
     },
 
     _select: function(num) {